#include "StdAfx.h"
#include "MD5Check.h"

#include <shlwapi.h>
#pragma comment(lib,"shlwapi.lib")

CMD5Check::CMD5Check(void)
{
}

CMD5Check::~CMD5Check(void)
{
}


BOOL CMD5Check::CheckMD5(LPCTSTR lpFile,DWORD dwPos,DWORD dwSpLen,LPCTSTR lpDM5Str)
{
	TCHAR MD5Str[0x21];
	if(!InputFile(lpFile,dwPos,dwSpLen,MD5Str))
		return FALSE;

	return StrCmpI(lpDM5Str,MD5Str)==0;
}


BOOL CMD5Check::InputFile(LPCTSTR lpFile,DWORD dwPos,DWORD dwSplen,LPTSTR lpOutStr)
{
	HANDLE hFile = CreateFile(lpFile,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	if(hFile == INVALID_HANDLE_VALUE)
		return FALSE;
	BOOL bCheck = InputFileHandle(hFile, dwPos, dwSplen,lpOutStr);
	CloseHandle(hFile);
	return bCheck;
}

BOOL CMD5Check::InputFileHandle(HANDLE hFile,DWORD dwPos,DWORD dwSplen,LPTSTR lpOutStr)
{
	if(!MD5Init)
	{
		HMODULE hMod = GetModuleHandle(_T("cryptdll.dll"));
		if(!hMod)
			hMod = LoadLibrary(_T("cryptdll.dll"));
		MD5Init = (PMD5Init)GetProcAddress(hMod,"MD5Init");
		MD5Update = (PMD5Update)GetProcAddress(hMod,"MD5Update");
		MD5Final= (PMD5Final)GetProcAddress(hMod,"MD5Final");
		if(!MD5Final || !MD5Update || !MD5Init)
			return FALSE;
	}
	if(hFile == INVALID_HANDLE_VALUE)
		return FALSE;

	LPBYTE lpBuffer = NULL; 
	DWORD dwLen,dwRead;
	dwLen = GetFileSize(hFile,NULL);

	if(dwPos>dwLen)
		return FALSE;
	if(dwSplen!=0&&dwSplen!=-1)
	{
		if((dwPos + dwSplen)>dwLen)
			return FALSE;
		dwLen = dwSplen;
	}

	if(dwPos!=0)
		SetFilePointer(hFile,dwPos,NULL,FILE_BEGIN);

	lpBuffer = new BYTE[dwLen];

	ReadFile(hFile,lpBuffer,dwLen,&dwRead,NULL);

	InputBuffer(lpBuffer,dwLen,lpOutStr);

	delete []lpBuffer;

	return TRUE;		

}

void CMD5Check::InputBuffer(LPBYTE lpBuffer,ULONG len,LPTSTR lpOutBuf)
{

	MD5_CTX _MD5CTX;
	MD5Init(&_MD5CTX);
	ZeroMemory(lpOutBuf,33);
	MD5Update(&_MD5CTX,lpBuffer,len);

	MD5Final(&_MD5CTX);

	for(int i=0;i<16;i++)
	{
		TCHAR t[3];
		_stprintf(t,_T("%02X"),_MD5CTX.digest[i]);
		StrCat(lpOutBuf,t);
	}
}